local Archy = LibStub("AceAddon-3.0"):GetAddon("Archy")
local Survey = Archy:NewModule("Survey", "AceEvent-3.0", "AceTimer-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("Archy")
local floor = floor
local db

function Survey:OnInitialize()
	db = Archy.db.profile
	self.frame = self:CreateIndicatorFrame()
end

function Survey:OnEnable()
	Archy.archData.RegisterCallback(self, "PlayerCastSurvey", "OnPlayerSurveyed")
	Archy.archData.RegisterCallback(self, "ReceivedFragments", "OnReceivedFragments")
	Archy.archData.RegisterCallback(self, "ArchNodeFound", "OnNodeFound")
	self:RegisterMessage("ArchyConfigChanged", "OnConfigChanged")
	self:RegisterMessage("ArchyPositionReset", "OnResetPosition")

	db = Archy.db.profile
	self.active = false
	self:SetScale()
	self:SetAlpha()
	self:ShowHide()

	self.updateTimer = self:ScheduleRepeatingTimer("Tick", 0.1)
end

function Survey:OnDisable()
	Archy.archData.UnregisterCallback(self, "PlayerCastSurvey")
	Archy.archData.UnregisterCallback(self, "ReceivedFragments")
	Archy.archData.UnregisterCallback(self, "ArchNodeFound")
	self:UnregisterMessage("ArchyConfigChanged")
	self:UnregisterMessage("ArchyPositionReset")
	if self.updateTimer then
		self:CancelTimer(self.updateTimer)
	end
end

function Survey:OnResetPosition()
	db = Archy.db.profile
	self.frame:ClearAllPoints()
	self.frame:SetPoint("CENTER", db.surveyIndicator.location.x, db.surveyIndicator.location.y)
end


function Survey:ShowHide()
	if db.surveyIndicator.enable and self.active then
		self.frame:Show()
	else
		self.frame:Hide()
	end
end

function Survey:SetScale()
	self.frame:SetScale(db.surveyIndicator.scale)
end

function Survey:SetAlpha()
	self.frame:SetAlpha(db.surveyIndicator.alpha)
end


function Survey:OnPlayerSurveyed(event, position, site)
	self.active = true
	self:ShowHide()
end

function Survey:OnNodeFound(event, race, position, site)
	self.active = false
	self:ShowHide()
end

function Survey:Tick()
	if not self.active then return end
	local lastPos = Archy.archData:GetLastSurveyPosition()
	if not lastPos then return end
	local playerPos = Archy.archData:GetPlayerPosition()
	
	local distance = Archy.astrolabe:ComputeDistance(playerPos.map, playerPos.floor, playerPos.x, playerPos.y, lastPos.map, lastPos.floor, lastPos.x, lastPos.y)
	if not distance or IsInInstance() then distance = 0 end
	
	local greenMin, greenMax = 0, db.surveyIndicator.greenDistance
	local yellowMin, yellowMax = greenMax, db.surveyIndicator.yellowDistance
	if yellowMax < yellowMin then yellowMax = yellowMin + 1 end
	local redMin, redMax = yellowMax, 500
	
	if distance >= greenMin and distance <= greenMax then
		self.frame.BackgroundTexture:SetTexture(0,1,0)
		self.frame.ColorText:SetText(L["Green"])
	elseif distance >= yellowMin and distance <= yellowMax then
		self.frame.BackgroundTexture:SetTexture(1,1,0)
		self.frame.ColorText:SetText(L["Yellow"])
	elseif distance >= redMin and distance <= redMax then
		self.frame.BackgroundTexture:SetTexture(1,0,0)
		self.frame.ColorText:SetText(L["Red"])
	else
		self.active = false
		self:ShowHide()
		return
	end
	distance = (floor(distance * 10) / 10)
	self.frame.DistanceText:SetText(string.format(L["%d yards"], distance))
end

function Survey:OnReceivedFragments(event, race, amount)
--	self.active = false
--	self:ShowHide()
end

function Survey:OnConfigChanged()
	db = Archy.db.profile
	self:ShowHide()
	self:SetScale()
	self:SetAlpha()
	
end

function Survey:CreateIndicatorFrame()
	local frame = CreateFrame("Frame", "ArchySurveyIndicator", UIParent)
	frame:EnableMouse(true)
	frame:SetMovable(true)
	frame:SetClampedToScreen(true)
	frame:SetScript("OnMouseDown", function(self, button)
		if not db.general.lock then
			if button == "LeftButton" and not self.isMoving then
				self:StartMoving()
				self.isMoving = true
			end
		end
	end)
	
	frame:SetScript("OnMouseUp", function(self, button)
		if not db.general.lock then
			if button == "LeftButton" and self.isMoving then
				self:StopMovingOrSizing()
				self.isMoving = false
				local point, relativeTo, relativePoint, x, y = self:GetPoint()
				db.surveyIndicator.location.x = x
				db.surveyIndicator.location.y = y
			end
		end
	end)
	
	frame:SetScript("OnHide", function(self)
		if self.isMoving then
			self:StopMovingOrSizing()
			self.isMoving = false
		end
	end)

	frame:SetWidth(20);
	frame:SetHeight(20);
	frame:SetPoint("CENTER", db.surveyIndicator.location.x, db.surveyIndicator.location.y)
	frame.BackgroundTexture = frame:CreateTexture("ARTWORK");
	frame.BackgroundTexture:SetAllPoints();
	frame.BackgroundTexture:SetTexture(1, 0 ,0);
	frame.ColorText = frame:CreateFontString("OVERLAY", nil, "GameFontHighlight");
	frame.ColorText:SetPoint("BOTTOM", frame, "TOP", 0, 0);
	frame.DistanceText = frame:CreateFontString("OVERLAY", nil, "GameFontHighlight");
	frame.DistanceText:SetPoint("TOP", frame, "BOTTOM", 0, 0);
	frame:Hide();

	return frame
end